package net.jjjshop.supplier.service.statistics.impl;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import net.jjjshop.common.entity.supplier.Supplier;
import net.jjjshop.common.entity.supplier.SupplierUser;
import net.jjjshop.common.param.HomeParam;
import net.jjjshop.common.param.HomeRankingParam;
import net.jjjshop.common.param.RankingParam;
import net.jjjshop.common.service.supplier.SupplierService;
import net.jjjshop.common.util.OrderDataUtils;
import net.jjjshop.common.util.ProductDataUtils;
import net.jjjshop.common.util.UserDataUtils;
import net.jjjshop.framework.common.exception.BusinessException;
import net.jjjshop.framework.util.SupplierLoginUtil;
import net.jjjshop.supplier.service.order.OrderRefundService;
import net.jjjshop.supplier.service.order.OrderService;
import net.jjjshop.supplier.service.product.ProductCommentService;
import net.jjjshop.supplier.service.product.ProductService;
import net.jjjshop.supplier.service.statistics.HomeDataService;
import net.jjjshop.supplier.service.statistics.ProductRankingService;
import net.jjjshop.supplier.service.supplier.SupplierUserService;
import net.jjjshop.supplier.service.user.UserFavoriteService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.Map;

/**
 * 首页统计数据 服务实现类
 * @author jjjshop
 * @since 2022-06-28
 */

@Slf4j
@Service
public class HomeDataServiceImpl implements HomeDataService {
    @Autowired
    private ProductCommentService productCommentService;
    @Autowired
    private OrderService orderService;
    @Autowired
    private OrderDataUtils orderDataUtils;
    @Autowired
    private OrderRefundService orderRefundService;
    @Autowired
    private ProductService productService;
    @Autowired
    private SupplierUserService supplierUserService;
    @Autowired
    private SupplierService supplierService;
    @Autowired
    private UserFavoriteService userFavoriteService;
    @Autowired
    private ProductDataUtils productDataUtils;
    @Autowired
    private UserDataUtils userDataUtils;
    @Autowired
    private ProductRankingService productRankingService;

    /**
     * 获取首页显示数据
     * @param
     * @return
     */
    @Override
    public JSONObject getHomeData(HomeParam param)  {
        JSONObject result = new JSONObject();
        Integer shopSupplierId = SupplierLoginUtil.getShopSupplierId();
        Supplier supplier = supplierService.getById(shopSupplierId);
        param.setShopSupplierId(shopSupplierId);
        if(supplier == null){
            throw new BusinessException("商户不存在");
        }
        result.put("top_data", this.getTopData(supplier));
        result.put("wait_data", this.getWaitData(supplier));
        //商品销售排行
        result.put("productRank", productRankingService.getSaleTimeRanking(param));
        //销售额概况
        result.put("saleData", this.getSaleData(param.getSaleTime(),shopSupplierId));
        //访客数据
        result.put("userData", this.getUserByDate(param.getUserTime(),shopSupplierId));
        //数据更新时间
        result.put("update_time", net.jjjshop.framework.util.DateUtil.getDateString(new Date()));
        return result;
    }

    private Map<String, Object> getUserByDate(Integer userTime, Integer shopSupplierId) {
        HomeRankingParam rankingParam = new HomeRankingParam();
        Date end = new Date();
        Date start = this.getStartDate(userTime,end);
        rankingParam.setStartDate(net.jjjshop.framework.util.DateUtil.getDateString(start));
        rankingParam.setEndDate(net.jjjshop.framework.util.DateUtil.getDateString(end));
        rankingParam.setType("order");
        rankingParam.setShopSupplierId(shopSupplierId);
        return userDataUtils.getUserByDate(rankingParam);
    }

    /**
     * 通过时间段查询订单数据
     */
    private Map<String, Object> getSaleData(Integer saleTime, Integer shopSupplierId) {
        RankingParam rankingParam = new RankingParam();
        Date end = new Date();
        Date start = this.getStartDate(saleTime,end);
        rankingParam.setStartDate(net.jjjshop.framework.util.DateUtil.getDateString(start));
        rankingParam.setEndDate(net.jjjshop.framework.util.DateUtil.getDateString(end));
        rankingParam.setType("order");
        rankingParam.setShopSupplierId(shopSupplierId);
        return orderDataUtils.getOrderDataByDate(rankingParam);
    }

    private Date getStartDate(Integer type, Date end) {
        //默认一个星期
        Date start = DateUtil.offsetDay(end,-7);
        //1=最近7天,2=最近15天,3=最近30天
        if(type != null && type == 2){
            start = DateUtil.offsetDay(end,-15);
        }
        if(type != null && type == 3){
            start = DateUtil.offsetDay(end,-30);
        }
        return start;
    }

    private JSONObject getWaitData(Supplier supplier) {
        Integer shopSupplierId = supplier.getShopSupplierId();
        JSONObject result = new JSONObject();
        // --订单待办--
        JSONObject order = new JSONObject();
        //待处理订单
        order.put("delivery", orderService.getReviewOrderTotal(shopSupplierId));
        //获取售后订单总量
        order.put("refund", orderRefundService.getRefundNum(shopSupplierId));
        result.put("order", order);
        // --商品待办--
        JSONObject product = new JSONObject();
        //审核
        product.put("audit", productDataUtils.getProductTotal(shopSupplierId, "audit",null));
        result.put("product", product);
        // --库存告急商品--
        JSONObject stock = new JSONObject();
        stock.put("product", productService.getProductStockTotal(shopSupplierId));
        result.put("stock", stock);
        return result;
    }

    private JSONObject getTopData(Supplier supplier) {
        Integer shopSupplierId = supplier.getShopSupplierId();
        JSONObject result = new JSONObject();
        Date today = new Date();
        Date yesterday = DateUtil.offsetDay(today, -1);
        // 商品总量
        result.put("product_total", productDataUtils.getProductTotal(shopSupplierId, "all",null));
        Long product_today = productDataUtils.getProductTotal(shopSupplierId, "all",today);
        Long product_yesterday = productDataUtils.getProductTotal(shopSupplierId, "all",yesterday);
        BigDecimal product_rate = product_yesterday >0 ? BigDecimal.valueOf(product_today - product_yesterday)
                .divide(BigDecimal.valueOf(product_yesterday), 2, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)) :
                BigDecimal.valueOf(product_today).multiply(BigDecimal.valueOf(100));
        result.put("product_today", product_today);
        result.put("product_yesterday", product_yesterday);
        result.put("product_rate", product_rate);
        // 订单总量
        result.put("order_total", this.getOrderTotal(null,shopSupplierId).intValue());
        Integer order_today = this.getOrderTotal(today,shopSupplierId).intValue();
        Integer order_yesterday = this.getOrderTotal(yesterday,shopSupplierId).intValue();
        BigDecimal order_rate = order_yesterday >0 ? BigDecimal.valueOf(order_today - order_yesterday)
                .divide(BigDecimal.valueOf(order_yesterday), 2, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)) :
                BigDecimal.valueOf(order_today).multiply(BigDecimal.valueOf(100));
        result.put("order_today", order_today);
        result.put("order_yesterday", order_yesterday);
        result.put("order_rate", order_rate);
        // 订单销售额
        result.put("total_money", this.getOrderTotalPrice(null,shopSupplierId));
        BigDecimal total_money_today = this.getOrderTotalPrice(today,shopSupplierId);
        BigDecimal total_money_yesterday = this.getOrderTotalPrice(yesterday,shopSupplierId);
        BigDecimal total_money_rate = total_money_yesterday.compareTo(BigDecimal.ZERO) >0 ?total_money_today.subtract(total_money_yesterday)
                .divide(total_money_yesterday, 2, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)) :
                total_money_today.multiply(BigDecimal.valueOf(100));
        result.put("total_money_today", total_money_today);
        result.put("total_money_yesterday", total_money_yesterday);
        result.put("total_money_rate", total_money_rate);
        // 店铺关注人数
        result.put("fav_count", supplier.getFavCount());
        Long fav_count_today = this.getFavUserTotal(today,shopSupplierId);
        Long fav_count_yesterday = this.getFavUserTotal(yesterday,shopSupplierId);
        BigDecimal fav_count_rate = fav_count_yesterday >0 ? BigDecimal.valueOf(fav_count_today - fav_count_yesterday)
                .divide(BigDecimal.valueOf(fav_count_yesterday), 2, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)) :
                BigDecimal.valueOf(fav_count_today).multiply(BigDecimal.valueOf(100));
        result.put("fav_count_today", fav_count_today);
        result.put("fav_count_yesterday", fav_count_yesterday);
        result.put("fav_count_rate", fav_count_rate);
        // 配送评分
        result.put("express_score", supplier.getExpressScore());
        // 服务评分
        result.put("server_score", supplier.getServerScore());
        // 描述评分
        result.put("describe_score", supplier.getDescribeScore());
        return result;
    }

    private Long getFavUserTotal(Date date, Integer shopSupplierId) {
        String startDate = null;
        String endDate = null;
        if(date != null){
            startDate = net.jjjshop.framework.util.DateUtil.getDateString(date);
            endDate = startDate;
        }
        //10店铺20商品
        return userDataUtils.getFavData(startDate, endDate,10, shopSupplierId);
    }

    /**
     * 获取某天的总销售额
     */
    private BigDecimal getOrderTotalPrice(Date date, Integer shopSupplierId) {
        String startDate = null;
        String endDate = null;
        if(date != null){
            startDate = net.jjjshop.framework.util.DateUtil.getDateStart(date);
            endDate = net.jjjshop.framework.util.DateUtil.getDateEnd(date);
        }
        return orderDataUtils.getOrderTotalPrice(startDate, endDate, shopSupplierId);
    }

    /**
     * 获取订单总数
     * @param
     * @return
     */
    public BigDecimal getOrderTotal(Date date,Integer shopSupplierId)  {
        String startDate = null;
        String endDate = null;
        if(date != null){
            startDate = net.jjjshop.framework.util.DateUtil.getDateString(date);
            endDate = startDate;
        }
        return orderDataUtils.getOrderData(startDate, endDate, "order_total", shopSupplierId);
    }

    /**
     * 获取首页显示数据
     * @param
     * @return
     */
    public JSONObject getHomeData()  {
        SupplierUser user = supplierUserService.getById(SupplierLoginUtil.getUserId());
        Integer shopSupplierId = user.getShopSupplierId();
        Supplier supplier = supplierService.getById(shopSupplierId);
        //获取今天时间
        String today = DateUtil.format(DateUtil.offsetDay(new Date(), 0), "yyyy-MM-dd");
        //获取昨天时间
        String yesterday = DateUtil.format(DateUtil.offsetDay(new Date(), -1), "yyyy-MM-dd");
        //获取七天前的时间
        String lately7days = DateUtil.format(DateUtil.offsetDay(new Date(), -7), "yyyy-MM-dd");

        // 商品总量
        Long productTotal = productService.getProductTotal(shopSupplierId);
        // 订单总量
        Integer orderTotal = Integer.parseInt(orderDataUtils.getOrderData(null,null,"order_total",shopSupplierId).toString());
        // 订单销售额
        BigDecimal totalMoney = orderDataUtils.getOrderData(null, null, "order_total_price",shopSupplierId);
        // 评价总量
        Long productCommentTotal = productCommentService.getProductCommentTotal(shopSupplierId);

        // 销售额(元)
        BigDecimal orderTotalPriceT = orderDataUtils.getOrderData(today, null, "order_total_price",shopSupplierId);
        BigDecimal orderTotalPriceY = orderDataUtils.getOrderData(yesterday, null, "order_total_price",shopSupplierId);

        // 支付订单数
        Integer orderTotalT = Integer.parseInt(orderDataUtils.getOrderData(today, null, "order_total",shopSupplierId).toString());
        Integer orderTotalY = Integer.parseInt(orderDataUtils.getOrderData(yesterday, null, "order_total",shopSupplierId).toString());

        //下单用户数
        Integer payOrderUserTotalT = orderService.getPayOrderUserTotal(today, shopSupplierId);
        Integer payOrderUserTotalY = orderService.getPayOrderUserTotal(yesterday, shopSupplierId);

        //店铺关注数
        Long favUserTotalT = userFavoriteService.getUserTotal(today, shopSupplierId);
        Long favUserTotalY = userFavoriteService.getUserTotal(yesterday, shopSupplierId);

        // 最近七天日期订单交易数
        Integer orderTotal7 = Integer.parseInt(orderDataUtils.getOrderData(lately7days, today, "order_total",shopSupplierId).toString());
        //最近七天订单交易金额
        BigDecimal orderTotalPrice7 = orderDataUtils.getOrderData(lately7days, today, "order_total_price",shopSupplierId);
        //待处理订单
        Long reviewOrderTotal = orderService.getReviewOrderTotal(shopSupplierId);
        //获取售后订单总量
        Long refundTotal = orderRefundService.getRefundNum(shopSupplierId);
        //获取提现订单总量
        Long cardOrderTotal = orderService.getCardOrderTotal(shopSupplierId);
        //未审核评论
        Long reviewCommentTotal = productCommentService.getReviewCommentTotal(shopSupplierId);
        //库存告急商品
        Long productStockTotal = productService.getProductStockTotal(shopSupplierId);

        JSONObject result = new JSONObject();
        result.put("productTotal", productTotal);
        result.put("orderTotal", orderTotal);
        result.put("productCommentTotal", productCommentTotal);
        //店铺关注数量
        result.put("favCount", supplier.getFavCount());
        result.put("expressScore", supplier.getExpressScore());
        result.put("serverScore", supplier.getServerScore());
        result.put("describeScore", supplier.getDescribeScore());
        result.put("totalMoney", totalMoney);

        result.put("orderTotalPriceT", orderTotalPriceT);
        result.put("orderTotalPriceY", orderTotalPriceY);

        result.put("orderTotalT", orderTotalT);
        result.put("orderTotalY", orderTotalY);
        result.put("payOrderUserTotalT", payOrderUserTotalT);
        result.put("payOrderUserTotalY", payOrderUserTotalY);
        result.put("favUserTotalT", favUserTotalT);
        result.put("favUserTotalY", favUserTotalY);

        result.put("orderTotal7", orderTotal7);
        result.put("orderTotalPrice7", orderTotalPrice7);
        result.put("reviewOrderTotal", reviewOrderTotal);
        result.put("refundTotal", refundTotal);
        result.put("cardOrderTotal", cardOrderTotal);
        result.put("reviewCommentTotal", reviewCommentTotal);
        result.put("productStockTotal", productStockTotal);

        return result;

    }
}
